package com.tidu.service;

import com.tidu.entry.ESDocument;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tidu.constants.DocumentConstant.ES_INDEX;

@Service
public class ElasticsearchService {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public void saveDocuments(String tableName, List<ESDocument> documents){
        List<IndexQuery> indexQueries = documents.stream().map(document -> new IndexQueryBuilder()
                .withId(generateDocId(tableName, document.getRowId()))
                .withObject(document)
                .build()
        ).collect(Collectors.toList());
        elasticsearchRestTemplate.bulkIndex(indexQueries, ESDocument.class);
    }

    /**
     * 生成ES文档ID（表名+主键）
     */
    private String generateDocId(String tableName, String rowId) {
        return tableName + ":" + rowId;
    }

    public List<ESDocument> search(String keyword, int maxResults) {
        List<ESDocument> results = new ArrayList<>();
        //Spring提供的一个查询条件构建器，帮助构建json格式的请求体
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        nativeSearchQueryBuilder
                .withQuery(QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("combinedText", keyword)))
                .withSorts(SortBuilders.scoreSort().order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, maxResults));
        NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
        try {
            //用els查询
            SearchHits<ESDocument> search = elasticsearchRestTemplate.search(searchQuery, ESDocument.class);
            search.getSearchHits().forEach(hit -> {
                ESDocument document = hit.getContent();
                System.out.println(document);
                results.add(document);
            });
        } catch (Exception e) {
            System.err.println("检索失败: " + e.getMessage());
            e.printStackTrace();
        }
        return results;
    }

    public void createIndexIfNotExists() {
        // 获取索引操作对象
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(ESDocument.class);

        // 检查索引是否存在，如果存在则删除
        if (indexOperations.exists()) {
            indexOperations.delete();
            System.out.println("已删除现有索引: " + ES_INDEX);
        }

        // 定义索引设置
        Map<String, Object> settings = new HashMap<>();
        settings.put("index.number_of_shards", 3);
        settings.put("index.number_of_replicas", 1);

        // 使用实体类自动生成映射
        boolean created = indexOperations.create(settings);
        // 单独创建映射（基于实体类注解）
        Document mapping = indexOperations.createMapping(ESDocument.class);
        indexOperations.putMapping(mapping);
//        boolean created = indexOperations.create(settings, mapping);
        if (created) {
            System.out.println("索引创建成功: " + ES_INDEX);
        } else {
            System.out.println("索引创建失败");
        }
    }
}
